package qa.tests;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Properties;

import org.apache.commons.io.FileUtils;

public class Statistics implements Statistic  {
    private int numberOfAsserts;

    private boolean exceptionThrown;

    private final Method forMethod;

    private Statistics(int numberOfAsserts, boolean exceptionThrown, Method method) {
        this(method);
        this.numberOfAsserts = numberOfAsserts;
        this.exceptionThrown = exceptionThrown;
    }
    
    public Statistics(Method forMethod) {
        this.forMethod = forMethod;
    }

    public Statistics increment() {
        numberOfAsserts++;
        return this;
    }

    public int numberOfAsserts() {
        return numberOfAsserts;
    }

    public Statistics exceptionThrown() {
        this.exceptionThrown = true;
        return this;
    }

    public boolean isExceptionThrown() {
        return exceptionThrown;
    }

    public void writeToFile(File inDirectory) {
        try {
            String fileName = fileName();
            FileUtils.writeLines(new File(inDirectory, fileName)
                                , Arrays.asList("asserts=" + numberOfAsserts
                                                , "exception=" + exceptionThrown));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private String fileName() {
        String className = forMethod.getDeclaringClass().getName();
        String methodName = forMethod.getName();
        String fileName = className + "." + methodName;
        return fileName;
    }

    public void increment(int numberOfTimesAssertCalled) {
        this.numberOfAsserts += numberOfTimesAssertCalled;
    }

    public static Statistic fromFile(File statisticsFile) {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream(statisticsFile));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        int asserts = Integer.valueOf(properties.getProperty("asserts"));
        boolean excpetion = Boolean.valueOf(properties.getProperty("exception"));
        String fileName = statisticsFile.getName();
        int lastIndexOfDot = fileName.lastIndexOf(".");
        String clazzName = fileName.substring(0, lastIndexOfDot);
        String methodName = fileName.substring(lastIndexOfDot + 1);
        Method method = null;
        try {
            ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
            method = contextClassLoader.loadClass(clazzName).getMethod(methodName, null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } 
        return new Statistics(asserts, excpetion, method);
    }
    
    public String getName() {
        return fileName();
    }
}
